#pragma once
#include "xDevice.h"
#include "xThread.h"
#include "xControl.h"
#include "d2d1helper.h"

struct ThreadProcParam
{
	WPARAM	_wParam;
	LPARAM	_lParam;
};

#define WM_DESTROYFRAME			(WM_USER + 0x3000)
#define WM_DESTROYFRAMERETURN	(WM_USER + 0x3001)

class xFrame : public xThread, public xDevice
{
public:
	xFrame();
	~xFrame();
protected:
	HWND				m_hWnd,
						m_hParent;
	xRenderView			*m_pRenderView;
	xRenderTarget		*m_pRenderUI;
	D3D_FEATURE_LEVEL	m_leavel;
	DXGI_ADAPTER_DESC1	m_adapter;
	BOOL				m_bRender;
	BOOL				m_bMouseEnter;
	xContainer			m_arrControl;
	FLOAT				m_crClear[4];
	UINT				m_nSyncInterval;
	RECT				m_rect;
	UINT				m_nSampleCount;
	AsyncParam			*m_pDestoyParam;
private:
	static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
	static ATOM RegisterClass(LPCWSTR szClassName);
protected:
	virtual BOOL OnWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
	virtual BOOL OnCreate(CREATESTRUCT *pCreate);
	virtual void OnDestroy();
	virtual void OnThreadProc(DWORD wParam, LPVOID lpParam);
	virtual void OnRender();
	virtual void OnDraw();
	virtual void OnKeyDown(DWORD dwKeyCode, DWORD dwFlags);
	virtual void OnKeyUp(DWORD dwKeyCode, DWORD dwFlags);
	virtual void OnLButtonDown(UINT nFlags, POINT point);
	virtual void OnLButtonUp(UINT nFlags, POINT point);
	virtual void OnMouseMove(UINT nFlags, POINT point);
	virtual void OnMouseLeave();
	virtual void OnMouseWheel(UINT nFlags, short zDelta, POINT point);
public:
	DWORD		Create(HWND hParent, LPCWSTR szTitle, const RECT &rect, DWORD style, UINT nSampleCount = 1);
	void		Destroy();
	AsyncParam	*DestroyAsync(DWORD nThreadIDReturn, WPARAM wParam = 0, LPARAM lParam = 0);
	void		InsertControl(xControl *pControl);
	void		SetClearColor(const D2D1::ColorF &color);
	void		SetSyncInterval(UINT nSyncInterval);
	HWND		GetHwnd();
	BOOL		ResizeBuffer(UINT width, UINT height);
	void		SetRender(BOOL bRender);
	void		SetFullscreen(BOOL bFullscreen = TRUE);
	BOOL		Reset(UINT nSampleCount);
	void		ResetSubControl(BOOL bReleaseOnly);
	void		SetRect(const RECT &rect);
};